

#include "client-interface-ui.h"

ClientInterfaceUI::ClientInterfaceUI(QWidget* parent, Qt::WFlags fl)
: QMainWindow( parent, fl ), Ui::windowMain()
{
	setupUi(this);
    // Connection Tab
    // verifica daca campurile de conexiune sunt goale... in cazul in care unul din ele e gol, se face disable la butonul de connect
    connect( lineEditServerAddress, SIGNAL( textChanged( const QString & ) ), this, SLOT( enable_connect_button() ) );
    connect( lineEditServerPort, SIGNAL( textChanged( const QString & ) ), this, SLOT( enable_connect_button() ) );
    connect( lineEditNick, SIGNAL( textChanged( const QString & ) ), this, SLOT( enable_connect_button() ) );
    connect( lineEditEmail, SIGNAL( textChanged( const QString & ) ), this, SLOT( enable_connect_button() ) );
    // cand se face click pe butonul de conect se trimite mesajul de login la server
    connect(buttonConnect, SIGNAL(clicked()), this, SLOT(send_login()));
    connect(buttonDisconnect, SIGNAL(clicked()), this, SLOT(send_logout()));
    connect(buttonSearch, SIGNAL(clicked()), this, SLOT(send_query()));

    // Config Tab - Add files to share
    connect(buttonAddFiles, SIGNAL(clicked()), this, SLOT(add_files_to_share()));

    // cand vine un mesaj, il proceseaza
    connect(&client_to_server_thread_, SIGNAL(message_received()), this, SLOT(process_pending_messages()));

    // se creaza socketul pe care se primesc mesaje de la server
    // trebuie citit din fisierul de configuratie portul pe care se face bind();
    client_to_server_thread_.create_recv_socket(6666);                // portul pe care asculta clientul pentru datagame de la server
    file_list_ = FileList();
    connected_ = false;
}

ClientInterfaceUI::~ClientInterfaceUI()
{
}

/*$SPECIALIZATION$*/

void ClientInterfaceUI::enable_connect_button()
{
    buttonConnect->setEnabled(!lineEditServerAddress->text().isEmpty() &&
                           !lineEditServerPort->text().isEmpty() &&
                           !lineEditNick->text().isEmpty() && 
                           !lineEditEmail->text().isEmpty() );
}

void ClientInterfaceUI::displaySocketError( int socketError, const QString &message ) {
    switch ( socketError ) {
        case QAbstractSocket::HostNotFoundError:
            QMessageBox::information( this, tr( "TADA Client" ),
                                      tr( "The host was not found. Please check the "
                                          "host and port settings." ) );

        break;
        case QAbstractSocket::ConnectionRefusedError:
            QMessageBox::information( this, tr( "TADA Client" ),
                                      tr( "The connection was refused by the peer. "
                                          "Make sure the fortune server is running, "
                                          "and check that the host name and port "
                                          "settings are correct." ) );

        break;
        default:
            QMessageBox::information( this, tr( "Blocking Fortune Client" ),
                                      tr( "The following error occurred: %1." )
                                      .arg( message ) );
    }
}

void ClientInterfaceUI::send_login()
{
    Message* message;
    ClientId client_id(143214);

    // te rog foloseste LOG(INFO) de acum incolo
    LOG(INFO) << "Trimit un mesaj de login";

    // construim mesajul 
    QByteArray nick, email;
    nick.append( lineEditNick->text() );
    email.append( lineEditEmail->text() );
    message = new messages::Login(
            client_id,
            quint32( inet_addr("127.0.0.1") ), quint16(6666),
            nick, email);

    // trimitem mesajul
    client_to_server_thread_.send_message(
            QHostAddress(lineEditServerAddress->text()).toIPv4Address(),
            lineEditServerPort->text().toInt(),
            message);
    textEditServerLog->append("Login message sent");
    textEditServerLog->append("Waiting for reply");
    //buttonConnect->setEnabled(false);
}

void ClientInterfaceUI::send_logout()
{
    Message* message;
    LOG(INFO) << "Trimit un mesaj de logout";
    message = new Message(messages::LOGOUT);
    // trimitem mesajul
    client_to_server_thread_.send_message(
            QHostAddress(lineEditServerAddress->text()).toIPv4Address(),
            lineEditServerPort->text().toInt(),
            message);
    textEditServerLog->append("Logout message sent");
    buttonConnect->setEnabled(true);
    buttonDisconnect->setEnabled(false);
    lineEditServerAddress->setEnabled(true);
    lineEditServerPort->setEnabled(true);
    lineEditNick->setEnabled(true);
    lineEditEmail->setEnabled(true);
    connected_ = false;
}

// daca se apasa pe butonul addFiles, se adauga fisiere la share
void ClientInterfaceUI::add_files_to_share()
{
     // se deschide un dialog din care se selecteaza fisierele
     QStringList files = QFileDialog::getOpenFileNames(
                         this,
                         "Select one or more files to add to share",
                         "/home",
                         "Files (*.*)");
    // daca nu s-a selectat nici un fisier se iese din functie
    if (files.isEmpty())
        return;
    // se adauga la tableSharedFiles fisierele adauate
    tableSharedFiles->setSortingEnabled(false);
    for (int i = 0; i < files.size(); ++i) 
    {
        // cream un fisier cu calea absoulta luata din lista de nume de fisier files
        QFile file(files[i]);
        // marimea fisierului
        qint32 size = QFileInfo(file).size();
        // numele fisierului
        QTableWidgetItem *itemFileName = new QTableWidgetItem(QFileInfo(file).baseName());
        itemFileName->setFlags(Qt::ItemIsEnabled);
        // calea fisierului
        QTableWidgetItem *itemFilePath = new QTableWidgetItem(QFileInfo(file).path());
        itemFilePath->setFlags(Qt::ItemIsEnabled);
        // initializam marimea fisierului file
        QTableWidgetItem *itemSize = new QTableWidgetItem(tr("%1 KB").arg(int((size + 1023) / 1024)));
        itemSize->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
        itemSize->setFlags(Qt::ItemIsEnabled);
        // extensia fisierului
        QTableWidgetItem *itemFileExtension = new QTableWidgetItem(QFileInfo(file).completeSuffix());
        itemFileExtension->setFlags(Qt::ItemIsEnabled);
        // adaugam in tabel cele 2 itemuri 
        int row = tableSharedFiles->rowCount();
        tableSharedFiles->insertRow(row);
        tableSharedFiles->setItem(row, 0, itemFileName);
        tableSharedFiles->setItem(row, 1, itemFilePath);
        tableSharedFiles->setItem(row, 2, itemSize);
        tableSharedFiles->setItem(row, 3, itemFileExtension);
        //LOG(INFO) << QFileInfo(file).path();
        
        //        LOG(INFO) << "nasol";
        FingerPrint finger_print;
        FingerPrint::hash(file, &finger_print);
        FileList::File fi = FileList::File((QFileInfo(file).baseName()).toLocal8Bit() , finger_print, size);
    }
    tableSharedFiles->setSortingEnabled(true);
    // TODO: se invoca threadul care face hash pentru a calcula hash-ul fisierleor adauate
}

void ClientInterfaceUI::process_pending_messages()
{
    LOG(INFO) << "mesaj nou de prelucrat";
    const Message* message = NULL;
    quint32 address;
    client_to_server_thread_.head_message(&message, &address);
    client_to_server_thread_.dequeue_message();
    if (message == NULL)
    {
        LOG(INFO) << "mesajul e null";
        return;
    }
    LOG(INFO) << "noul mesaj e de tip " << message->type();
    switch ( message->type() )
    {
        case messages::ACK_LOGIN:
            textEditServerLog->append("Connected");
            buttonConnect->setEnabled(false);
            buttonDisconnect->setEnabled(true);
            lineEditServerAddress->setEnabled(false);
            lineEditServerPort->setEnabled(false);
            lineEditNick->setEnabled(false);
            lineEditEmail->setEnabled(false);
            connected_ = true;
            send_file_list();
        break;
        case messages::NACK_LOGIN:
        break;
        case messages::ACK_LIST_SEGMENT:
        break;
        case messages::ACK_LIST_FINSIH:
        break;
        case messages::S_QUERY_RESULT:
        break;
        case messages::ACK_LIST_HEAD:
        break;
        case messages::NACK_LIST_HEAD:
        break;
    }
}

void ClientInterfaceUI::send_file_list()
{

}

void ClientInterfaceUI::send_query()
{
    Message* message;
    message = new messages::SQuery(QByteArray((lineEditSearch->text()).toStdString().c_str()), 1234);
    LOG(INFO) << (lineEditSearch->text()).toStdString().c_str();
    // trimitem mesajul
    client_to_server_thread_.send_message(
            QHostAddress(lineEditServerAddress->text()).toIPv4Address(),
            lineEditServerPort->text().toInt(),
            message);
}
